package com.mutouren.modules.org.client.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.tuple.ImmutablePair;

import com.google.common.cache.Cache;
import com.mutouren.common.cache.local.GuavaCacheUtils;
import com.mutouren.common.cache.local.GuavaCacheUtils.ExpireType;
import com.mutouren.common.entity.ResultCode;
import com.mutouren.common.entity.ResultInfo;
import com.mutouren.modules.org.client.proxy.OrgApiProxy;
import com.mutouren.modules.org.model.Function;

public class FunctionConfig {
	
	private static Cache<String, Object> cache = GuavaCacheUtils.createCache(10, TimeUnit.MINUTES, ExpireType.expireAfterWrite);	
		
	private static FunctionConfig instance;
	private FunctionConfig() {		
		
	}
	
	public synchronized static FunctionConfig getInstance() {
		if (instance == null) {
			instance = new FunctionConfig();
		}
		return instance;
	}
	
	private static ImmutablePair<List<Function>, Map<String, Integer>> toImmutablePair(List<Function> listFunction) {
		Map<String, Integer> mapFunction = new HashMap<String, Integer>();
		for(Function obj : listFunction) {
			mapFunction.put(obj.getUrl(), obj.getFuncId());
		}
		
		return new ImmutablePair<List<Function>, Map<String, Integer>>(listFunction, mapFunction);
	}
	
	public synchronized Map<String, Integer> getMapUrlOfApp() {
		return getFunctionPairOfApp().getRight();
	}
	
	public synchronized List<Function> getAllFunctionOfApp() {
		return getFunctionPairOfApp().getLeft();
	}
	
	private synchronized ImmutablePair<List<Function>, Map<String, Integer>> getFunctionPairOfApp() {
		String key = String.format("appAlias_%s", ClientConfig.getAppAlias());
		
		@SuppressWarnings("unchecked")
		ImmutablePair<List<Function>, Map<String, Integer>> cacheFunctions = 
			(ImmutablePair<List<Function>, Map<String, Integer>>)cache.getIfPresent(key);
		if (cacheFunctions != null) {
			return cacheFunctions;
		}
		
		//System.out.println("load...");
		ResultInfo<List<Function>> resultInfo = OrgApiProxy.getFunctionsOfApp(ClientConfig.getAppAlias());
		if (resultInfo.getCode() == ResultCode.SUCCESS.value) {
			ImmutablePair<List<Function>, Map<String, Integer>> pair = toImmutablePair(resultInfo.getInfo());
			cache.put(key, pair);
			return pair;
		} else {
			return toImmutablePair(new ArrayList<Function>());
		}
	}
	
	public synchronized int[] getFunctionIdsOfUser(int userId) {
		String key = String.format("userId_%s", userId);
		
		int[] cacheFunctionIds = (int[])cache.getIfPresent(key);
		if (cacheFunctionIds != null) {
			return cacheFunctionIds;
		}		
		
		ResultInfo<int[]> resultInfo = OrgApiProxy.getFunctionIdsOfUser(userId, ClientConfig.getAppAlias());
		if (resultInfo.getCode() == ResultCode.SUCCESS.value) {
			cache.put(key, resultInfo.getInfo());
			return resultInfo.getInfo();
		} else {
			return new int[]{};
		}
	}
}
